﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Tracy.BasicServices;
using Tracy.DataModel;
using Tracy;
using Tracy.Messages;
using Tracy.Handlers;
using SharedLib.MessageFramework;
using System.IO;
using SharedLib.Exceptions;
using TracyGUI.UIComponent;
using System.Threading;
using System.Diagnostics;

namespace TracyGUI
{
    public partial class FormMain : Form
    {
        
        private delegate void UpdateUICallbackMessage(object sender, NotifyUIEventArgs e);//TODO: Move to General Lib
        private delegate void ExceptionCallbackMessage(object sender, ExceptionEventArgs e);//TODO: Move to General Lib

        private object _notificationLock = new object();
        private void MessageDispatcher_OnNotifyUI(object sender, NotifyUIEventArgs e)
        {
            if (this.IsDisposed) return;
            if (this.InvokeRequired)
            {
                UpdateUICallbackMessage d = new UpdateUICallbackMessage(MessageDispatcher_OnNotifyUI);
                this.Invoke(d, new object[] { sender, e });
            }
            else
            {
                lock (_notificationLock)
                {
                    switch (e.EventType)
                    {
                        case NotifyUIEventArgs.FOUND_RESOURCE:
                            OnFoundResource(e);
                            break;
                        case NotifyUIEventArgs.FILE_UPDATED :
                            OnFileUpdated(e);
                            break;
                        case NotifyUIEventArgs.MESSAGE_PROCESSING:
                            OnMessageProcessing(e);
                            break;
                        case NotifyUIEventArgs.MESSAGE_PROCESSED:
                            OnMessageProcessed(e);
                            break;
                        case NotifyUIEventArgs.NEW_VERSION_FOUND:
                            OnNewVersionFound(e);
                            break;
                    }
                }
            }
        }

        private void OnNewVersionFound(NotifyUIEventArgs e)
        {
            if (MessageBox.Show("New version found: " + e.Param as string + "\nWould you like to check?", "New version found", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
            {
                Process.Start("http://tracy.codeplex.com");
            }
        }

        private int _processingMessages = 0;
        private void OnMessageProcessed(NotifyUIEventArgs e)
        {
            int currentProcessingMessages = Interlocked.Decrement(ref _processingMessages);
            if (currentProcessingMessages <= 0) toolStripStatusLabelMain.Text = "Ready";
        }

        private void OnMessageProcessing(NotifyUIEventArgs e)
        {
            int currentProcessingMessages = Interlocked.Increment(ref _processingMessages);
            toolStripStatusLabelMain.Text = String.Format("Processing {0} Tasks", currentProcessingMessages);
        }

        private void OnFileUpdated(NotifyUIEventArgs e)
        {
            List<MediaFile> fileList = e.Param as List<MediaFile>;
            foreach (MediaFile file in fileList)
            {
                ChangeMediaFileStatus(file, file.Status);
                if (file.Properties.ContainsKey(MediaFile.KEY_PREVIOUS_PATH))
                {
                    FileMoved(file);
                }
            }
        }



        
        private void OnFoundResource(NotifyUIEventArgs e)
        {
            List<Resource> resourceList = e.Param as List<Resource>;
            for (int i = resourceList.Count - 1; i >= 0; i--) //sort desc
            {
                Resource res = resourceList[i];
                if (_mappingEntry.ContainsKey(res.Entry.ID))
                {
                    AddNewResource(res);
                    //TracyBus.Instance.ResourceProvider.AddItem(res);
                    //if (WillAddItemToUI(res)) AddItemToResourceListView(res);
                }
                if (IsAutoDownloadMode)
                {
                    SendResourceToDownload(res);
                }
                else
                {
                    _formNewResourceSelection.AddItem(new ListBoxItemResource(res));
                }
            }

        }

        private void FoundNewResource_SelectionConfirmed(object sender, GenericEventArgs<List<ListBoxItemResource>> e)
        {
            foreach (ListBoxItemResource resWrapper in e.Data)
            {
                Resource res = resWrapper.Data;
                SendResourceToDownload(res);
            }
        }

        FormConsole _formConsole;
        private void MessageDispatcher_OnException(object sender, SharedLib.Exceptions.ExceptionEventArgs e)
        {
            if (this.IsDisposed) return;
            if (this.InvokeRequired)
            {
                ExceptionCallbackMessage d = new ExceptionCallbackMessage(MessageDispatcher_OnException);
                this.Invoke(d, new object[] { sender, e });
            }
            else
            {
                if (_formConsole == null || _formConsole.IsDisposed) _formConsole = new FormConsole();
                _formConsole.AppendMessage(GetExceptionContent(e.EmbededException));
                //_formConsole.AppendMessage(e.StackTrace);
                _formConsole.Show();
            }
            
        }

        private string GetExceptionContent(Exception ex)
        {
            if (ex == null) return null;
            StringWriter sw = new StringWriter();
            Exception tmp = ex;
            while (tmp != null)
            {
                sw.WriteLine(ex.Message);
                sw.WriteLine(ex.StackTrace);
                tmp = tmp.InnerException;
            }
            return sw.ToString();
        }
        
    }


}
